﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WITM.DAL;
using WITM.BLL;
using WITM.Util;

namespace WITMTestApplication
{
    public partial class StatsTestForm : Form
    {
        private UserBL userBl;
        private SpendingEntryBL spendingEntryBl;
        private ChartProvider chartProvider;

        public StatsTestForm()
        {
            InitializeComponent();
            InitializeDB(false);
            InitializeItemsGrid();
            InitializeGroupingCombo();
            LoadUsersComboBox();
            radioEver.Checked = true;
            chartProvider = new ChartProvider();
            btnGetStats_Click(btnGetStats, EventArgs.Empty);
        }

        private enum GroupingOption
        {
            Item,
            Category,
            Day
        }


        private void InitializeGroupingCombo()
        {
            cbGrouping.DataSource = Enum.GetValues(typeof(GroupingOption));
            cbGrouping.SelectedItem = GroupingOption.Category;
        }

        private void LoadUsersComboBox()
        {
            IEnumerable<Users> users = userBl.GetAll();
            var usersFormated = from u in users
                                select new
                                {
                                    ID = u.UserID,
                                    Name = String.Format("{0} {1}", u.FirstName, u.LastName)
                                };
            cbUsers.ValueMember = "ID";
            cbUsers.DisplayMember = "Name";
            cbUsers.DataSource = usersFormated.ToList();
        }

        private void InitializeDB(bool tracking)
        {
            WhereIsTheMoneyDBEntities context = new WhereIsTheMoneyDBEntities();
            if (!tracking)
            {
                context.Users.MergeOption = System.Data.Objects.MergeOption.NoTracking;
                context.SpendingCategories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
                context.SpendingItems.MergeOption = System.Data.Objects.MergeOption.NoTracking;
                context.SpendingEntries.MergeOption = System.Data.Objects.MergeOption.NoTracking;
            }
            UnitOfWork unitOfWork = new UnitOfWork(context);
            userBl = new UserBL(unitOfWork);
            spendingEntryBl = new SpendingEntryBL(unitOfWork);
        }

        private void InitializeItemsGrid()
        {
            dgvTopItems.Columns.Add("colID", "ID");
            dgvTopItems.Columns["colID"].Visible  = false;
            dgvTopItems.Columns.Add("colDescription", "Description");
            dgvTopItems.Columns.Add("colTotal", "Total");
        }

        private void radio_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton radio = sender as RadioButton;
            bool enable = radio == radioLastNDays;
            dtpStartDate.Enabled = enable;
            dtpEndDate.Enabled = enable;
            txtDays.Enabled = enable;

            if (radio == radioThisWeek)
            {
                DateTime startDate = GetThisMonday(DateTime.Today);
                dtpStartDate.Value = startDate;
                dtpEndDate.Value = startDate.AddDays(6);
            }
            else if (radio == radioThisMonth)
            {
                DateTime startDate = DateTime.Today.AddDays(-(DateTime.Today.Day - 1));
                dtpStartDate.Value = startDate;
                dtpEndDate.Value = startDate.AddMonths(1).AddDays(-1);
            }
            else if (radio == radioThisYear)
            {
                DateTime startDate = DateTime.Today.AddDays(-(DateTime.Today.DayOfYear - 1));
                dtpStartDate.Value = startDate;
                dtpEndDate.Value = startDate.AddYears(1).AddDays(-1);
            }
            else if (radio == radioLastNDays)
            {
                int numDays = 0;
                if (Int32.TryParse(txtDays.Text, out numDays))
                {
                    SetLastDays(numDays);
                }
            }
            else if (radio == radioEver)
            {
                dtpStartDate.Value = dtpStartDate.MinDate;
                dtpEndDate.Value = dtpEndDate.MaxDate;
            }
            else if (radio == radioCustom)
            {
                dtpStartDate.Enabled = true;
                dtpEndDate.Enabled = true;
            }
        }

        private void SetLastDays(int numDays)
        {
            dtpEndDate.Value = DateTime.Today;
            dtpStartDate.Value = DateTime.Today.AddDays(-(numDays - 1));
        }

        private DateTime GetThisMonday(DateTime date)
        {
            while (date.DayOfWeek != DayOfWeek.Monday)
            {
                date = date.AddDays(-1);
            }
            return date;
        }

        private void btnGetStats_Click(object sender, EventArgs e)
        {
            int userID = (int)cbUsers.SelectedValue;
            List<SpendingSum> spendingSum = null;
            GroupingOption grouping = (GroupingOption)cbGrouping.SelectedItem;
            if (grouping == GroupingOption.Category)
            {
                spendingSum = radioEver.Checked ?
                    spendingEntryBl.GetTotalCategories(userID) :
                    spendingEntryBl.GetTotalCategories(userID, dtpStartDate.Value, dtpEndDate.Value);
                dgvTopItems.Rows.Clear();
            }
            else if (grouping == GroupingOption.Item)
            {
                spendingSum = radioEver.Checked ?
                    spendingEntryBl.GetTotalItems(userID) :
                    spendingEntryBl.GetTotalItems(userID, dtpStartDate.Value, dtpEndDate.Value);
                dgvTopItems.Rows.Clear();
            }
            else if (grouping == GroupingOption.Day)
            {
                spendingSum = radioEver.Checked ?
                    spendingEntryBl.GetTotalDays(userID) :
                    spendingEntryBl.GetTotalDays(userID, dtpStartDate.Value, dtpEndDate.Value);
                dgvTopItems.Rows.Clear();
            }

            foreach (SpendingSum sum in spendingSum)
            {
                dgvTopItems.Rows.Add(sum.ID, 
                    grouping != GroupingOption.Day ? sum.Description : sum.Date.ToString("yyyy-MM-dd"), 
                    sum.Amount);
            }
            lblTotal.Text = String.Format("Total: {0}", spendingSum.Sum(s => s.Amount));
            if (grouping == GroupingOption.Day)
            {
                pbChart.Image = chartProvider.GetChart(pbChart.Size.Width - 5, 
                    pbChart.Size.Height - 5, 
                    spendingSum);
            }
            else if (grouping == GroupingOption.Category)
            {
                pbChart.Image = chartProvider.GetPie(pbChart.Size.Width - 5,
                    pbChart.Size.Height - 5,
                    spendingSum);
            }
            else
            {
                pbChart.Image = null;
            }
        }

        private void txtDays_TextChanged(object sender, EventArgs e)
        {
            int numDays = 0;
            if (Int32.TryParse(txtDays.Text, out numDays))
            {
                SetLastDays(numDays);
            }
        }
    }
}
